package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"vpn/guard/config"
	"vpn/guard/device"
	"vpn/guard/network"
	"vpn/guard/utils"
)

// 适用于linux的入口
func main() {
	configPath := flag.String("config", "config.json", "Path to configuration file")
	flag.Parse()

	// Load configuration
	cfg, err := config.LoadConfig(*configPath)
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}
	mtu := 1420
	if cfg.Mtu != 0 {
		mtu = cfg.Mtu
	}
	// Create and setup tunnel
	tunnel, err := network.NewTun(cfg.Address, mtu)
	if err != nil {
		log.Fatalf("Failed to create tunnel: %v", err)
	}

	//尝试执行 post_up 命令，来开启流量转发等功能
	utils.ExecCmd(cfg.PostUp)
	defer utils.ExecCmd(cfg.PostDown)

	deviceTunnel := &device.DeviceTunnel{
		Close: func() error {
			fmt.Println("TUN device closed 0")
			return tunnel.Close()
		},
		Write: func(data []byte) (int, error) {
			return tunnel.Write(data)
		},
		Read: func(data []byte) (int, error) {
			return tunnel.Read(data)
		},
		Name: func() string {
			return tunnel.Name()
		},
		Mtu: func() int {
			return mtu
		},
	}
	// Create device
	device_ := device.NewDevice(device.NewDeviceParams{
		Tun:    deviceTunnel,
		Config: cfg,
	})
	device_.AllowedIPs.RLock()
	for _, allowedIP := range device_.AllowedIPs.AllowedIPs {
		utils.ExecCmd(fmt.Sprintf("ip route add %s dev %s", allowedIP.IP.String(), device_.Tun.Name()))
	}
	device_.AllowedIPs.RUnlock()
	device_.UpDevice()
	sigCh := make(chan os.Signal, 1)
	// Wait for shutdown signal
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh
	device_.DownDevice()
}
